package exp.parser;

import grammar.parser.FuncFParams;
import word.parser.WordElement;

import java.util.ArrayList;
import java.util.List;

public class AddExp extends ExpParser {
    private final ExpParser left;
    private final ExpParser right;
    private final boolean isPlus;

    public AddExp(ExpParser left, ExpParser right, boolean isPlus) {
        super(left.isComputable() && (right == null || right.isComputable()),
                left.isConst() && (right == null || right.isConst()));
        this.left = left;
        this.right = right;
        this.isPlus = isPlus;
    }

    public static AddExp parserAddExp() {
        List<ExpParser> expParserList = new ArrayList<>();
        List<Boolean> plusFlagList = new ArrayList<>();
        expParserList.add(MulExp.parseMulExp());
        ExpParser left = expParserList.get(0);
        while (getAnalyzingWord().getType() == WordElement.WordType.PLUS ||
                getAnalyzingWord().getType() == WordElement.WordType.MINU) {
            Boolean isPlus = getAnalyzingWord().getType() == WordElement.WordType.PLUS;
            analyzeNextWord();
            plusFlagList.add(isPlus);
            expParserList.add(MulExp.parseMulExp());
        }
        plusFlagList.add(true);
        for (int i = 1; i <= expParserList.size(); i++) {
            ExpParser right = i < expParserList.size() ? expParserList.get(i) : null;
            left = new AddExp(left, right, plusFlagList.get(i - 1));
        }
        return (AddExp) left;
    }

    @Override
    public LVal toLVal() {
        if (right == null) {
            return left.toLVal();
        }
        return null;
    }

    @Override
    public Integer compute() {
        Integer value = null;
        if (isComputable()) {
            value = left.getValue();
            if (right != null) {
                value += (isPlus ? 1 : -1) * right.getValue();
            }
        }
        return value;
    }

    @Override
    public FuncFParams.FuncFParam checkDimension() {
        if (right != null) {
            return new FuncFParams.FuncFParam();
        }
        return left.checkDimension();
    }
}
